package com.navinfo.tripanalysis.offline.service.impl;

import com.navinfo.tripanalysis.common.util.CommonUtils;
import com.navinfo.tripanalysis.offline.accumulator.DCConstants;
import com.navinfo.tripanalysis.common.pojo.Point;
import com.navinfo.tripanalysis.common.pojo.Point0F37;
import com.navinfo.tripanalysis.common.util.BigDecimalUtils;
import com.navinfo.tripanalysis.offline.pojo.Abnormal0F37DataDetail;
import com.navinfo.tripanalysis.offline.service.DataCleaning0F37Service;
import com.navinfo.tripanalysis.offline.util.AccumulatorUtils;
import com.navinfo.tripanalysis.offline.util.DataNode;
import com.navinfo.tripanalysis.offline.util.OutlierNodeDetect;
import lombok.Data;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.function.PairFlatMapFunction;
import org.apache.spark.util.AccumulatorV2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.Tuple2;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
@Data
public class DataCleaning0F37ServiceImpl implements DataCleaning0F37Service, Serializable {

    private static final Logger logger = LoggerFactory.getLogger(DataCleaning0F37Service.class);
    private  double Acceleration_Max_Threshold;
    private double Speed_Max_Threshold;
    private int Rotation_Max_Threshold;
    private double LatLon_Max_Threshold;
    private double AvgSpeed_Weight_Threshold;
    private double MidSpeed_Weight_Threshold;
    //初始化各统计指标
    //车辆上传记录数
    private int point_count = 0;
    //gpstime重复记录数
    private int repeated_gpstime_count = 0;
    //速度异常记录数
    private int abnormal_speed_count = 0;
    //转速异常记录数
    private int abnormal_rotation_count = 0;
    //经纬度坐标异常记录数
    private int abnormal_latlon_count = 0;
    //速度异常范围
    //速度150-200
    private int speedRange_150_200_count = 0;
    //速度150-200
    private int speedRange_200_500_count = 0;
    //速度150-200
    private int speedRange_500_count = 0;
    //转速异常范围
    //转速2000-3000
    private int rotationRange_3000_4000_count = 0;
    //转速2000-3000
    private int rotationRange_4000_5000_count = 0;
    //转速2000-3000
    private int rotationRange_5000_count = 0;

    @Override
    public JavaPairRDD<Long,Tuple2<Abnormal0F37DataDetail, List<Point0F37>>> getAbnormalData(JavaPairRDD<Long, List<Point>> pointsRdd, AccumulatorV2<String, String> acc0f37) {

        //统计异常数据
        JavaPairRDD<Long,Tuple2<Abnormal0F37DataDetail, List<Point0F37>>> resultRdd =
                pointsRdd.mapPartitionsToPair((PairFlatMapFunction<Iterator<Tuple2<Long, List<Point>>>, Long, Tuple2<Abnormal0F37DataDetail, List<Point0F37>>>) tuple ->
                new Iterator<Tuple2<Long, Tuple2<Abnormal0F37DataDetail, List<Point0F37>>>>() {
                    @Override
                    public boolean hasNext() {
                        return tuple.hasNext();
                    }

                    @SneakyThrows
                    @Override
                    public Tuple2<Long, Tuple2<Abnormal0F37DataDetail, List<Point0F37>>> next() {
                        Tuple2<Long, List<Point>> tuple0 = tuple.next();
                        Long tid = tuple0._1;
                        List<Point> points = tuple0._2;
                        //当天上传0f37点数量
                        point_count = points.size();
                        //判断初始坐标是否发生漂移
                        if(point_count >= 100) {
                            checkFirstPoint(points, Math.min((int) (points.size() * 0.01), 100) + 10);
                        }
                        //数据去重结果
                        List<Point0F37> resultPoint = new ArrayList<>();
                        //前五个点的速度，用于计算平均速度和中位数速度
                        List<Point0F37> tmpPointList = new ArrayList<>();
                        long lastgpstime = 0;
                        Point0F37 tmp;
                        //遍历当日车辆全部位置点，统计异常数据
                        for(Point p0:points){
                            Point0F37 p = (Point0F37) p0;
                            //如果gpstime重复，则记录加1，过滤该记录
                            if(p.getGpsTime() == lastgpstime){
                                ++repeated_gpstime_count;
                            }else{
                                double time = BigDecimalUtils.divide(p.getGpsTime() - lastgpstime,1000,3).doubleValue();
                                //
                                tmp = (Point0F37)p.clone();
                                //判断速度异常
                                speedStatistics(p,tmp,tmpPointList,time);
                                //判断转速异常
                                rotaionStatistics(p,tmp,tmpPointList);
                                //经纬度坐标异常
                                latlonStatistics(p,tmp,tmpPointList,time);
                                //去重后数据
                                resultPoint.add(p);
                                //替换当前点速度到数组钟
                                if(tmpPointList.size() >= 5){
                                    tmpPointList.remove(0);
                                }
                                tmpPointList.add(tmp);
                            }
                            lastgpstime = p.getGpsTime();
                        }

                        //累加相应数值
                        //统计当天车辆总数
                        acc0f37.add(DCConstants.ACC_0F37_COUNT);
                        int repeated_point_ratio = BigDecimalUtils.divide(repeated_gpstime_count*100,point_count,0).intValue();
                        if(repeated_point_ratio > 0){
                            acc0f37.add(calculateRepeatedPoint(repeated_point_ratio));
                        }
                        if(abnormal_speed_count >= 10){
                            acc0f37.add(calculateSpeed(abnormal_speed_count));
                        }
                        if(abnormal_rotation_count >= 10){
                            acc0f37.add(calculateRotation(abnormal_rotation_count));
                        }
                        //汇总异常数据明细
                        Abnormal0F37DataDetail data = null;
                        if(abnormal_speed_count + abnormal_rotation_count + abnormal_latlon_count> 0
                                || repeated_gpstime_count >= 100){
                            data = new Abnormal0F37DataDetail();
                            data.setTid(tid);
                            data.setPoint_count(point_count);
                            data.setRepeated_gpstime_count(repeated_gpstime_count);
                            data.setSpeedRange_150_200_count(speedRange_150_200_count);
                            data.setSpeedRange_200_500_count(speedRange_200_500_count);
                            data.setSpeedRange_500_count(speedRange_500_count);
                            data.setRotationRange_3000_4000_count(rotationRange_3000_4000_count);
                            data.setRotationRange_4000_5000_count(rotationRange_4000_5000_count);
                            data.setRotationRange_5000_count(rotationRange_5000_count);
                            data.setLatlon_count(abnormal_latlon_count);
                        }
                        //初始化各统计指标
                        //车辆上传记录数
                        point_count = 0;
                        //gpstime重复记录数
                        repeated_gpstime_count = 0;
                        //速度异常记录数
                        abnormal_speed_count = 0;
                        //转速异常记录数
                        abnormal_rotation_count = 0;
                        //经纬度坐标异常记录数
                        abnormal_latlon_count = 0;
                        //速度异常范围
                        //速度150-200
                        speedRange_150_200_count = 0;
                        //速度150-200
                        speedRange_200_500_count = 0;
                        //速度150-200
                        speedRange_500_count = 0;
                        //转速异常范围
                        //转速2000-3000
                        rotationRange_3000_4000_count = 0;
                        //转速2000-3000
                        rotationRange_4000_5000_count = 0;
                        //转速2000-3000
                        rotationRange_5000_count = 0;
                        return new Tuple2<>(tid,new Tuple2<>(data,resultPoint));
                    }
                });
        return resultRdd;
    }

    /**
     * 判断速度值是否异常，并按范围区分统计
     * @param p
     * @param
     */
    private void speedStatistics(Point0F37 p,Point0F37 tmp,List<Point0F37> tmpPointList,double time){

        //计算当前点加速度,单位m/s2
        double acceleration = time==0.0?0.0:CommonUtils.isCollectionEmpty(tmpPointList)?0.0:BigDecimalUtils.divide(BigDecimalUtils.divide((p.getSpeedKmh() - tmpPointList.get(tmpPointList.size() - 1).getSpeedKmh()),3.6,2).doubleValue(),time,2).doubleValue();
        if (p.getSpeedKmh() > Speed_Max_Threshold || acceleration > Acceleration_Max_Threshold){

            ++abnormal_speed_count;
            //按范围统计异常速度
            setSpeedRange(p.getSpeedKmh());

            if(CommonUtils.isCollectionEmpty(tmpPointList)){
                return;
            }

            //标记需要修正数据
            //暂不修正数据
//            p.setDataUpd(p.getDataUpd()==null?DCConstants.UPDFIELD_SPEED+"="+p.getSpeedKmh()
//                    :"|"+DCConstants.UPDFIELD_SPEED+"="+p.getSpeedKmh());
            //修正速度异常数据
            double avgSpeed = getAvgSpeed(tmpPointList);
            double midSpeed = tmpPointList.get(tmpPointList.size() / 2).getSpeedKmh();
            double updSpeed = BigDecimalUtils.multiply(avgSpeed,AvgSpeed_Weight_Threshold,2).doubleValue()
                    + BigDecimalUtils.multiply(midSpeed,MidSpeed_Weight_Threshold,2).doubleValue();
            //标记需要修正数据
            //修正速度记录到修正列，后续确认无误，再调整更新速度值
            p.setDataUpd(StringUtils.isEmpty(p.getDataUpd())?DCConstants.UPDFIELD_SPEED+"="+updSpeed
                    :p.getDataUpd()+"|"+DCConstants.UPDFIELD_SPEED+"="+updSpeed);
            tmp.setSpeedKmh(updSpeed);
            //p.setSpeedKmh(updSpeed);
//          //按范围统计异常速度

        }
    }

    /**
     * 判断经纬度坐标是否发生漂移
     * @param p
     * @param tmpPointList
     * @param time
     */
    private void latlonStatistics(Point0F37 p,Point0F37 tmp,List<Point0F37> tmpPointList,double time){
        //第一个点不处理
        if(CommonUtils.isCollectionEmpty(tmpPointList)){
            return;
        }
        //计算经纬度坐标变化差值
        double latLonDiff = time==0?0.0:BigDecimalUtils.divide(getLatLonDiff(p,tmpPointList),time,2).doubleValue();
        if(latLonDiff <= LatLon_Max_Threshold){
            return;
        }
        if(time <= 0){
            return;
        }
        int newLat = 0;
        int newLon = 0;
        double curSpeed = StringUtils.isEmpty(AccumulatorUtils.getFieldFromConcatString(p.getDataUpd(),"\\|",DCConstants.UPDFIELD_SPEED))?
                p.getSpeedKmh():
                Double.parseDouble(AccumulatorUtils.getFieldFromConcatString(p.getDataUpd(),"\\|",DCConstants.UPDFIELD_SPEED));
        if(curSpeed == 0){
            //如果当前点速度为0，取上一点坐标作为当前点坐标
            newLat = tmpPointList.get(tmpPointList.size() - 1).getOriginalLat();
            newLon = tmpPointList.get(tmpPointList.size() - 1).getOriginalLng();
        }else if(curSpeed > 0){
            //通过前一点坐标、方向、距离预估当前点坐标
            Point0F37 prePoint = tmpPointList.get(tmpPointList.size() - 1);
            //距离,单位：km
            double distance = time*(curSpeed+prePoint.getSpeedKmh())/(2*3600);
            //方向
            double direction = tmpPointList.size()<2? 90:
                    AccumulatorUtils.getDirection(prePoint.getOriginalLat()*Math.pow(10,-6), prePoint.getOriginalLng()*Math.pow(10,-6),
                            tmpPointList.get(tmpPointList.size() - 2).getOriginalLat()*Math.pow(10,-6),
                            tmpPointList.get(tmpPointList.size() - 2).getOriginalLng()*Math.pow(10,-6));
            Tuple2<Double,Double> newLatLon =
                    AccumulatorUtils.getLatLon(prePoint.getOriginalLat()*Math.pow(10,-6), prePoint.getOriginalLng()*Math.pow(10,-6),
                            distance,direction);
            newLat = BigDecimalUtils.multiply(newLatLon._1,1000000,0).intValue();
            newLon = BigDecimalUtils.multiply(newLatLon._2,1000000,0).intValue();
        }
        //修正结果记录到修正值列
        String updString = DCConstants.UPDFIELD_0F37_ORIGINALLAT+"="+newLat+"|"+DCConstants.UPDFIELD_0F37_ORIGINALLNG+"="+newLon;
        p.setDataUpd(StringUtils.isEmpty(p.getDataUpd())?updString :p.getDataUpd()+"|"+updString);
        tmp.setOriginalLng(newLon);
        tmp.setOriginalLat(newLat);
        ++abnormal_latlon_count;

    }

    /**
     * 将速度按范围统计
     * @param speed
     */
    private void setSpeedRange(Double speed){
        if(speed > 150 && speed <= 200){
            ++speedRange_150_200_count;
        }else if (speed > 200 && speed <= 500){
            ++speedRange_200_500_count;
        }else if (speed > 500){
            ++speedRange_500_count;
        }
    }

    /**
     * 判断转速异常，并按范围区分
     * @param p
     */
    private void rotaionStatistics(Point0F37 p,Point0F37 tmp,List<Point0F37> tmpPointList){

        if (p.getRotation() > Rotation_Max_Threshold){

            ++abnormal_rotation_count;
            //按范围统计异常速度
            setRotationRange(p.getRotation());

            if(CommonUtils.isCollectionEmpty(tmpPointList)){
                return;
            }

            int avgRotation = getAvgRotation(tmpPointList);
            int midRotation = tmpPointList.get(BigDecimal.valueOf(tmpPointList.size()).divide(new BigDecimal(2),0,BigDecimal.ROUND_DOWN).intValue()).getRotation();
            int updRotation = BigDecimalUtils.multiply(AvgSpeed_Weight_Threshold,avgRotation,0).intValue()
                    + BigDecimalUtils.multiply(MidSpeed_Weight_Threshold,midRotation,0).intValue();

            String updString = DCConstants.UPDFIELD_ROTATION+"="+updRotation;
            //修正值记录
            p.setDataUpd(StringUtils.isEmpty(p.getDataUpd())? updString:p.getDataUpd()+"|"+updString);
            tmp.setRotation(updRotation);
            //标记异常值
//            p.setDataUpd(p.getDataUpd()==null? DCConstants.UPDFIELD_ROTATION+"="+p.getRotation()
//                    :p.getDataUpd()+"|"+DCConstants.UPDFIELD_ROTATION+"="+p.getRotation());
            //按范围统计异常速度
            //暂不修正数据
//            p.setDataUpd(p.getDataUpd()==null? DCConstants.UPDFIELD_ROTATION+"="+p.getRotation()
//                    :p.getDataUpd()+"|"+DCConstants.UPDFIELD_ROTATION+"="+p.getRotation());
//
        }
    }

    /**
     * 按范围统计转速异常点
     * @param rotation
     */
    private void setRotationRange(int rotation){
        if(rotation > 3000 && rotation <= 4000){
            ++rotationRange_3000_4000_count;
        }else if (rotation > 4000 && rotation <= 5000){
            ++rotationRange_4000_5000_count;
        }else if (rotation > 5000){
            ++rotationRange_5000_count;
        }
    }

    private String calculateSpeed(int abnormal_speed_count){

        if(abnormal_speed_count >= 10 && abnormal_speed_count < 100){
            return DCConstants.ACC_0F37_SPEED_10_100_COUNT;
        }else if(abnormal_speed_count >= 100 && abnormal_speed_count < 300){
            return DCConstants.ACC_0F37_SPEED_100_300_COUNT;
        }else if(abnormal_speed_count >= 300){
            return DCConstants.ACC_0F37_SPEED_300_COUNT;
        }
        return null;
    }

    private String calculateRotation(int abnormal_rotation_count){

        if(abnormal_rotation_count >= 10 && abnormal_rotation_count < 100){
            return DCConstants.ACC_0F37_ROTATION_10_100_COUNT;
        }else if(abnormal_rotation_count >= 100 && abnormal_rotation_count < 300){
            return DCConstants.ACC_0F37_ROTATION_100_300_COUNT;
        }else if(abnormal_rotation_count >= 300){
            return DCConstants.ACC_0F37_ROTATION_300_COUNT;
        }
        return null;
    }

    private String calculateRepeatedPoint(int repeated_point_ratio){
        if(repeated_point_ratio > 0 && repeated_point_ratio <= 10){
            return DCConstants.ACC_0F37_REPEATED_0_10_Ratio;
        }else if(repeated_point_ratio > 10 && repeated_point_ratio <= 50){
            return DCConstants.ACC_0F37_REPEATED_10_50_Ratio;
        }else if(repeated_point_ratio > 50){
            return DCConstants.ACC_0F37_REPEATED_50_Ratio;
        }
        return null;
    }

    private double getAvgSpeed (List<Point0F37> tmpPointList){
        double sum = 0.0;
        for (Point0F37 lastSpeed : tmpPointList){
            sum += lastSpeed.getSpeedKmh();
        }
        double avgSpeed = BigDecimalUtils.divide(sum,tmpPointList.size(),2).doubleValue();
        return avgSpeed;
    }

    private int getAvgRotation (List<Point0F37> tmpPointList){
        double sum = 0.0;
        for (Point0F37 lastRotation : tmpPointList){
            sum += lastRotation.getRotation();
        }
        int avgRotation = BigDecimalUtils.divide(sum,tmpPointList.size(),0).intValue();
        return avgRotation;
    }

    private double getLatLonDiff (Point0F37 p,List<Point0F37> tmpPointList){
        if(CommonUtils.isCollectionEmpty(tmpPointList)){
            return 0;
        }
        String curLatUpd = AccumulatorUtils.getFieldFromConcatString(p.getDataUpd(),"\\|",DCConstants.UPDFIELD_0F37_ORIGINALLAT);
        String curLonUpd = AccumulatorUtils.getFieldFromConcatString(p.getDataUpd(),"\\|",DCConstants.UPDFIELD_0F37_ORIGINALLNG);
        double curLat = BigDecimalUtils.divide(StringUtils.isEmpty(curLatUpd)?p.getOriginalLat():Integer.parseInt(curLatUpd),1000000,6).doubleValue();
        double curLon = BigDecimalUtils.divide(StringUtils.isEmpty(curLonUpd)?p.getOriginalLng():Integer.parseInt(curLonUpd),1000000,6).doubleValue();
        Point0F37 pre = tmpPointList.get(tmpPointList.size() - 1);
        String preLatUpd = AccumulatorUtils.getFieldFromConcatString(pre.getDataUpd(),"\\|",DCConstants.UPDFIELD_0F37_ORIGINALLAT);
        String preLonUpd = AccumulatorUtils.getFieldFromConcatString(pre.getDataUpd(),"\\|",DCConstants.UPDFIELD_0F37_ORIGINALLNG);
        double preLat = BigDecimalUtils.divide(StringUtils.isEmpty(preLatUpd)?pre.getOriginalLat():Integer.parseInt(preLatUpd),1000000,6).doubleValue();
        double preLon = BigDecimalUtils.divide(StringUtils.isEmpty(preLonUpd)?pre.getOriginalLng():Integer.parseInt(preLonUpd),1000000,6).doubleValue();
        return AccumulatorUtils.getLatLonDiffence(curLat,curLon,preLat,preLon);
    }

    private void checkFirstPoint (List<Point> points , int sampleNum){
        if(CommonUtils.isCollectionEmpty(points)) return;
        List<DataNode> dpoints = new ArrayList<>();
        //int num = Math.max(points.size(),sampleNum);
        //取出样本数据
        Point0F37 pre = null;
        int nodename = 0;
        for(int i=0;i<sampleNum;i++){

            Point0F37 p = (Point0F37)points.get(i);
            //如果当前点未移动，则过滤
            if(pre != null) {
                if (p.getSpeedKmh() == 0 && p.getOriginalLat() == pre.getOriginalLat() && p.getOriginalLng() == pre.getOriginalLng()) {
                    continue;
                }
            }
            double[] latlon = new double[]{p.getOriginalLng(),p.getOriginalLat()};
            dpoints.add(new DataNode(nodename,latlon,i));
            nodename++;
            pre = p;
        }
        if(dpoints.size() >= 50) {
            //计算样本中每个点局部离群点因子
            List<DataNode> resllt = OutlierNodeDetect.getOutlierNode(dpoints);
            //找到第一个局部离群点因子在范围内的点，重新计算该点之前的经纬度坐标
            updFirstPoint(points, resllt);
        }
    }

    private void updFirstPoint(List<Point> points, List<DataNode> nodes){
        if(CommonUtils.isCollectionEmpty(nodes))return;
        //如果第一个点未发生漂移则不需要修改坐标
        if(nodes.get(0).getLof() <= 2)return;
        for(int i=0;i<nodes.size();i++){

            if(nodes.get(i).getLof() > 2){
                //如果发生漂移，则跳过
                continue;
            }else {
                //找到第一个未发生漂移的位置点，修正该点之前的经纬度坐标
                //修正第一个正常点之前的经纬度
                //得到过滤停车点前位置点序号
                int pointnum = nodes.get(i).getPointNum();
                Point0F37 p0 = (Point0F37)points.get(pointnum);
                Point0F37 p1 = (Point0F37)points.get(pointnum+1);
                //找下一个正常点
                for(int m=pointnum+1;m<nodes.size();m++){
                    if(p0.getOriginalLng() == points.get(m).getOriginalLng()
                            && p0.getOriginalLat() == points.get(m).getOriginalLat()
                            && p0.getGpsTime() < points.get(m).getGpsTime()
                            && nodes.get(m).getLof() <= 2) {
                            continue;
                        }else{
                        p1 = (Point0F37)points.get(m);
                        break;
                    }
                }
                //计算前两个正常点的方向
                double direction = AccumulatorUtils.getDirection(p0.getOriginalLat()*Math.pow(10,-6), p0.getOriginalLng()*Math.pow(10,-6),
                        p1.getOriginalLat()*Math.pow(10,-6),
                        p1.getOriginalLng()*Math.pow(10,-6));
                Point0F37 pre= p0;
                //处理之前错误的经纬度
                for (int j=pointnum-1 ;j>=0;j--){
                    int newLat = 0;
                    int newLon = 0;
                    int preLat = AccumulatorUtils.getFieldFromConcatString(pre.getDataUpd(),"\\|",DCConstants.UPDFIELD_0F37_ORIGINALLAT)==null?
                            pre.getOriginalLat():
                            Integer.parseInt(AccumulatorUtils.getFieldFromConcatString(pre.getDataUpd(),"\\|",DCConstants.UPDFIELD_0F37_ORIGINALLAT));;
                    int preLon = AccumulatorUtils.getFieldFromConcatString(pre.getDataUpd(),"\\|",DCConstants.UPDFIELD_0F37_ORIGINALLNG)==null?
                            pre.getOriginalLng():
                            Integer.parseInt(AccumulatorUtils.getFieldFromConcatString(pre.getDataUpd(),"\\|",DCConstants.UPDFIELD_0F37_ORIGINALLNG));;
                    Point0F37 cur = (Point0F37) points.get(j);
                    if(pre.getSpeedKmh()+cur.getSpeedKmh() == 0 || pre.getGpsTime() == cur.getGpsTime()){
                        newLat = preLat;
                        newLon = preLon;
                    }else{
                        //距离,单位：km
                        double distance = ((pre.getGpsTime() - cur.getGpsTime())/1000)*(pre.getSpeedKmh()+cur.getSpeedKmh())/(2*3600);
                        Tuple2<Double,Double> newLatLon =
                                AccumulatorUtils.getLatLon(preLat*Math.pow(10,-6), preLon*Math.pow(10,-6),
                                        distance,direction);
                        //计算出前一点的经纬度坐标
                        newLat = BigDecimalUtils.multiply(newLatLon._1,1000000,0).intValue();
                        newLon = BigDecimalUtils.multiply(newLatLon._2,1000000,0).intValue();
                    }
                    //更新坐标
                    //修正结果记录到修正值列

                    String updString = DCConstants.UPDFIELD_0F37_ORIGINALLAT+"="+newLat+"|"+DCConstants.UPDFIELD_0F37_ORIGINALLNG+"="+newLon;
//                    String updString = DCConstants.UPDFIELD_0F37_ORIGINALLAT+"="+points.get(j).getOriginalLat()+"|"+DCConstants.UPDFIELD_0F37_ORIGINALLNG+"="+points.get(j).getOriginalLng();
                    Point0F37 upd = (Point0F37)points.get(j);
                    upd.setDataUpd(upd.getDataUpd()==null?updString :upd.getDataUpd()+"|"+updString);

//                    //更新原始点坐标
//                    upd.setOriginalLat(newLat);
//                    upd.setOriginalLng(newLon);
                    ++abnormal_latlon_count;

                    if(cur.getOriginalLng() != pre.getOriginalLng()
                            || cur.getOriginalLat() != pre.getOriginalLat()){
                        //更新方向，下一次计算使用
                        direction = AccumulatorUtils.getDirection(newLat*Math.pow(10,-6), newLon*Math.pow(10,-6),
                                preLat*Math.pow(10,-6),
                                preLon*Math.pow(10,-6));
                    }
                    pre = cur;
                }break;  //更新到第一个点后，跳出循环
            }

        }
    }
}
